// 版权归 Epic Games, Inc. 所有，保留所有权利。

#pragma once

#include "CommonUserWidget.h"
#include "Widgets/SLeafWidget.h"

#include "LyraPerfStatWidgetBase.generated.h"

enum class ELyraDisplayablePerformanceStat : uint8;

class ULyraPerformanceStatSubsystem;
class UObject;
struct FFrame;
class FSampledStatCache;

/**
 * SLyraLatencyGraph
 *
 * 用于绘制延迟图表的 Slate 叶控件。
 */
class SLyraLatencyGraph : public SLeafWidget
{
public:
	/** 开始定义此 Slate 控件的参数 */
	SLATE_BEGIN_ARGS(SLyraLatencyGraph)
		: _DesiredSize(150, 50), // 期望尺寸
		_MaxLatencyToGraph(33.0), // 图表最大延迟值
		_LineColor(255, 255, 255, 255), // 线条颜色
		_BackgroundColor(0, 0, 0, 128) // 背景颜色
	{
		_Clipping = EWidgetClipping::ClipToBounds; // 裁剪方式
	}

	SLATE_ARGUMENT(FVector2D, DesiredSize) // 期望尺寸参数
	SLATE_ARGUMENT(double, MaxLatencyToGraph) // 最大延迟参数
	SLATE_ARGUMENT(FColor, LineColor) // 线条颜色参数
	SLATE_ARGUMENT(FColor, BackgroundColor) // 背景颜色参数
	SLATE_END_ARGS()

	/** 每个控件都需要构造函数 */
	void Construct(const FArguments& InArgs); // 构造函数

	/** 绘制时调用 */
	virtual int32 OnPaint(const FPaintArgs& Args, // 绘制函数
		const FGeometry& AllottedGeometry,
		const FSlateRect& MyClippingRect,
		FSlateWindowElementList& OutDrawElements,
		int32 LayerId,
		const FWidgetStyle& InWidgetStyle,
		bool bParentEnabled) const override;

	virtual bool ComputeVolatility() const override { return true; } // 计算易变性
	
	virtual FVector2D ComputeDesiredSize(float LayoutScaleMultiplier) const override; // 计算期望尺寸

	inline void SetLineColor(const FColor& InColor) // 设置线条颜色
	{
		LineColor = InColor;	
	}

	inline void SetMaxYValue(const double InValue) // 设置Y轴最大值
	{
		MaxYAxisOfGraph = InValue;
	}

	inline void SetBackgroundColor(const FColor& InColor) // 设置背景颜色
	{
		BackgroundColor = InColor;
	}

	inline void UpdateGraphData(const FSampledStatCache* StatData, const float InScaleFactor) // 更新图表数据
	{
		GraphData = StatData;
		ScaleFactor = InScaleFactor;
	}
	
private:
	
	void DrawTotalLatency(const FGeometry& AllottedGeometry, FSlateWindowElementList& OutDrawElements, int32 LayerId) const; // 绘制总延迟

	/**
	 * 要绘制的图表尺寸
	 */
	FVector2D DesiredSize = { 150.0, 50.0 }; // 期望尺寸

	/**
	 * 图表的Y轴最大值。绘制的值将被限制在此范围内
	 */
	double MaxYAxisOfGraph = 33.0; // Y轴最大值

	float ScaleFactor = 1.0f; // 缩放因子

	/**
	 * 图表上绘制的线条颜色
	 */
	FColor LineColor = FColor(255, 255, 255, 255); // 线条颜色

	/**
	 * 绘制图表时绘制的背景颜色
	 */
	FColor BackgroundColor = FColor(0, 0, 0, 128); // 背景颜色

	/**
	 * 此图表控件需要绘制的数据缓存
	 */
	const FSampledStatCache* GraphData = nullptr; // 图表数据
};

/**
 * ULyraPerfStatGraph
 *
 * 用于显示统计信息随时间变化图表的控件基类。
 */
UCLASS(meta = (DisableNativeTick)) // 禁用原生Tick
class ULyraPerfStatGraph : public UUserWidget
{
	GENERATED_BODY()

public:
	ULyraPerfStatGraph(const FObjectInitializer& ObjectInitializer); // 构造函数
	
	void SetLineColor(const FColor& InColor); // 设置线条颜色
	
	void SetMaxYValue(const float InValue); // 设置Y轴最大值
	
	void SetBackgroundColor(const FColor& InValue); // 设置背景颜色

	void UpdateGraphData(const FSampledStatCache* StatData, const float ScaleFactor); // 更新图表数据
	
protected:
	// 开始 UWidget 接口
	virtual TSharedRef<SWidget> RebuildWidget() override; // 重建控件
	virtual void ReleaseSlateResources(bool bReleaseChildren) override; // 释放 Slate 资源
	// 结束 UWidget 接口

	// 实际绘制图表的 Slate 控件。在 RebuildWidget 中创建，在 ReleaseSlateResources 中销毁。
	TSharedPtr<SLyraLatencyGraph> SlateLatencyGraph; // Slate 延迟图表控件
};

/**
 * ULyraPerfStatWidgetBase
 *
 * 用于显示单个统计信息（例如 FPS、ping 等）的控件基类。
 */
 UCLASS(Abstract) // 抽象类
class ULyraPerfStatWidgetBase : public UCommonUserWidget
{
public:
	GENERATED_BODY()

public:
	// 返回此控件应显示的统计信息
	UFUNCTION(BlueprintPure) // 蓝图纯函数
	ELyraDisplayablePerformanceStat GetStatToDisplay() const // 获取要显示的统计信息
	{
		return StatToDisplay;
	}

	// 轮询此统计信息的值（未缩放）
	UFUNCTION(BlueprintPure) // 蓝图纯函数
	double FetchStatValue(); // 获取统计值

	UFUNCTION(BlueprintCallable) // 蓝图可调用函数
	void UpdateGraphData(const float ScaleFactor = 1.0f); // 更新图表数据

protected:

 	virtual void NativeConstruct() override; // 原生构造函数

 	ULyraPerformanceStatSubsystem* GetStatSubsystem(); // 获取统计子系统

	/**
	 * 可选的统计图表控件，用于显示此统计信息随时间变化的值。
	 */
	UPROPERTY(BlueprintReadWrite, meta=(BindWidget, OptionalWidget=true)) // 蓝图读写，绑定控件，可选控件
 	TObjectPtr<ULyraPerfStatGraph> PerfStatGraph; // 性能统计图表控件
 	
	// 缓存的子系统指针
	UPROPERTY(Transient) // 瞬态属性
	TObjectPtr<ULyraPerformanceStatSubsystem> CachedStatSubsystem; // 缓存的统计子系统

 	UPROPERTY(EditAnywhere, Category = Display) // 可在任意位置编辑，显示类别
 	FColor GraphLineColor = FColor(255, 255, 255, 255); // 图表线条颜色
	
 	UPROPERTY(EditAnywhere, Category = Display) // 可在任意位置编辑，显示类别
 	FColor GraphBackgroundColor = FColor(0, 0, 0, 128); // 图表背景颜色

 	/**
	  * Y轴的最大值，用于限制图表的显示范围。
	  */
 	UPROPERTY(EditAnywhere, Category = Display) // 可在任意位置编辑，显示类别
 	double GraphMaxYValue = 33.0; // 图表Y轴最大值

	// 要显示的统计信息
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Display) // 可在任意位置编辑，蓝图只读，显示类别
	ELyraDisplayablePerformanceStat StatToDisplay; // 要显示的统计信息
 };